﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Events;
using System.Windows.Input;
using System.Windows;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using SoonCode.Core;
using SoonCode.FocusTest.Events;
using SoonCode.FocusTest.Models;
using SoonCode.FocusTest.Utils;
using System.Windows.Threading;

namespace SoonCode.FocusTest.ViewModels
{
    internal class TestItemHViewModel : BindableBase
    {
        private int TestItemIndex = 8;
        private string itemType = "itemH";
        private RandomHelper randomHelper;
        private int tabIndex = 0;
        private int err = 0;
        private TestInfo testInfo;
        private IEventAggregator aggregator;
        private IDialogService dialogService;
        private DateTime startTime;
        private SubscriptionToken answerToken;
        private int currTime = 0;
        private DispatcherTimer timer;
        private int currIndex = 0;
        private EventInfo questEventInfo;
        private ObservableCollection<HItemHelper> sourceList;
        private string helpSoundText = "停止播放提示语";
        private bool helpIsPlay = true;

        public string HelpSoundText
        {
            get { return helpSoundText; }
            set
            {
                helpSoundText = value;
                RaisePropertyChanged();
            }
        }

        public ObservableCollection<HItemHelper> SourceList
        {
            get { return sourceList; }
            set
            {
                sourceList=value;
                RaisePropertyChanged();
            }
        }

        public int CurrTime
        {
            get { return currTime; }
            set
            {
                currTime = value;
                RaisePropertyChanged();
            }
        }

        public TestItemHViewModel(IEventAggregator aggregator, IDialogService dialogService)
        {
            
            this.aggregator = aggregator;
            this.dialogService = dialogService;
            questEventInfo=new EventInfo(itemType);
            if (timer == null) timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.IsEnabled = false;
            timer.Tick += Timer_Tick; ;
            aggregator.GetEvent<EndTestEvent>().Subscribe(() =>
            {
                timer.Stop();
                aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
                answerToken = null;

            });
            aggregator.GetEvent<ChangeTestEvent>().Subscribe(TestChange);
            aggregator.GetEvent<TestLoadEvent>().Subscribe(OnLoaded);

        }

        private void TestChange(int p)
        {
            timer.Stop();
        }

        private void Timer_Tick(object? sender, EventArgs e)
        {
            CurrTime = (int)(DateTime.Now - startTime).TotalSeconds;
            questEventInfo.Data["currTime"] = CurrTime;
            this.aggregator.GetEvent<QuestionChangeEvent>().Publish(questEventInfo);
            if (currTime >= 120)
            {
                SoundPlayer.PlayDing();
                timer.Stop();
                complete();
            }
        }

        private void OnLoaded(int p)
        {
            if (p != this.TestItemIndex - 1)
            {
                if (answerToken != null)
                {
                    aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
                    answerToken = null;
                }

                return;
            }
            int age = GlobalModel.Instance.MemberInfo.age;
            if (age >= 5) randomHelper = new RandomHelper(1, 6);
            else randomHelper = new RandomHelper(1, age+1);
            this.testInfo = GlobalModel.Instance.TestInfo;
            TabIndex = 0;
            CurrTime = 0;
            Task.Run(GenerateList);
            if(answerToken==null)
                answerToken = aggregator.GetEvent<StudentAnswerEvent>().Subscribe(SutdentAnswer);
            SoundPlayer.Play("1000:item8.mp3");
        }

        private void SutdentAnswer(EventInfo payload)
        {
            if (payload == null || payload.Type != itemType)
            {
                return;
            }

            int index = Convert.ToInt16(payload.Data["index"]);
            HItemHelper helper = SourceList[currIndex];
            helper.answer = index;
            SourceList[currIndex].color = "";
            if (index==helper.source)
                SourceList[currIndex].color = "Green";

            SourceList[currIndex].answerImg = $"pack://application:,,,/Images/hc{index}.png";
            currIndex++;
            if (currIndex >= 100)
            {
                complete();
                return;
            }
            SourceList[currIndex].color = "Red";
        }
        public int TabIndex
        {
            get { return tabIndex; }
            set
            {
                tabIndex = value;
                RaisePropertyChanged();
            }
        }

        public ICommand HelpCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    if (helpIsPlay)
                    {
                        SoundPlayer.Stop();
                        HelpSoundText = "播放提示语";
                        helpIsPlay = false;
                    }
                    else
                    {
                        SoundPlayer.Play("item8.mp3");
                        HelpSoundText = "停止播放提示语";
                        helpIsPlay = true;
                    }
                });
            }
        }
        public ICommand SkipCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
                });
            }
        }
        public ICommand StartCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    TabIndex = 1;
                    currIndex = 0;
                    startTime = DateTime.Now;
                    timer.Start();
                    Test();
                });
            }
        }

        public ICommand AnswerErrorCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    
                });
            }
        }
        public ICommand AnswerRightCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    complete();
                });
            }
        }

        private void GenerateList()
        {
            string s = randomHelper.next(100);
            SourceList = new ObservableCollection<HItemHelper>();
            foreach (char c in s)
            {
                HItemHelper helper = new HItemHelper();
                helper.source = c.ToString().ToInt();
                helper.img = $"pack://application:,,,/Images/hs{helper.source}.png";
                SourceList.Add(helper);
            }

        }
        private void complete()
        {
            int count=SourceList.Where(f => f.source == f.answer).Count();
            string s = DialogUtil.Prompt(dialogService, "请输入正确个数", (p) =>
            {
                int r;
                if (int.TryParse(p, out r))
                {
                    if (r > 0 && r <= 100) return true;
                    return false;
                }
                else
                {
                    return false;
                }

            },count.ToString());
            int num = s.ToInt();
            DialogUtil.Show(this.aggregator, $"正确个数=（{num}）个，本项结束，进入下一项");
            testInfo.data[TestItemIndex].item_score = (int)num + "";
            this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
        }
        private async void Test()
        {
            EventInfo eventInfo=new EventInfo();
            eventInfo.Type = itemType;
            eventInfo.Data["source"] = SourceList;
            this.aggregator.GetEvent<StudentStartTestEvent>().Publish(eventInfo);
            SourceList[currIndex].color = "Red";
        }
    }

    public class HItemHelper:BindableBase
    {
        private string _img = "";
        private string _color = "";
        private string _answerImg = "";

        public Thickness answerMargin
        {
            get
            {

                Thickness margin = new Thickness();
                switch (source)
                {
                    case 2:
                        margin.Top = 5;
                        return margin;
                    case 5:
                        margin.Top = 8;
                        return margin;
                    default:
                        return margin;
                }

            }
        }

        public string answerImg
        {
            get { return _answerImg; }
            set
            {
                _answerImg=value;
                RaisePropertyChanged();
            }
        }
        public string color
        {
            get { return _color; }
            set
            {
                _color=value;
                RaisePropertyChanged();
            }
        }

        public string img
        {
            get { return _img; }
            set
            {
                _img = value;
                RaisePropertyChanged();
            }
        }
        public int source { get; set; }
        public int answer { get; set; }
    }
}
